<template>
    <li class="c-tree-node" v-show="!node.isHidden">
        <div :class="classItem" :style="stylesItem" @click="handleSelect">
            <span :class="classBtn" @click="handleClickOpen"></span>

            <c-checkbox v-if="showCheck" v-model="checkVal" @on-change="handleCheck"></c-checkbox>

            <span class="c-tree-icon" v-if="node.showIcon">
                <c-icon :name="iconName" size="16" color="#666"></c-icon>
            </span>

            <span class="c-tree-txt" :title="node.title || node.name">{{ node.name }}</span>
        </div>

        <ul v-if="isOpen" :class="classUl" :style="stylesUl">
            <c-treenode v-for="(child, idx) in node.children" :key="child.id"
                        :node="child" :set="set" :level="level + 1"
                        :last="idx === node.children.length - 1"
            ></c-treenode>
        </ul>
    </li>
</template>

<script>

    import { emitUp } from '../vueTools';

    export default {
        name: "CTreenode",
        props: {
            // 配置
            set: {type: Object, default() { return {};}},
            // 节点原数据
            node: {type: Object, default() { return {};}},
            // 层级
            level: {type: Number, default: 1},
            // 是否为最后一个子节点
            last: Boolean,
        },
        data() {
            return {
                raw: this.node.raw,
                isOpen: this.node.open, // 是否展开子节点
                checkVal: this.node.checked, // 是否选中
                emitUp: emitUp.bind(this),
            };
        },
        computed: {
            // 是否显示多选框
            showCheck() {
                return this.set.check.show === 'checkbox' && !this.node.nocheck;
            },
            // 是否可以单选
            showRadio() {
                return this.set.check.show === 'radio' && !this.node.disabled;
            },
            // 节点结构背景图标
            classBtn() {
                const open = this.isOpen; // 是否展开
                const parent = this.node.isParent; // 是否为父节点
                const hasChild = !!this.node.children.length; // 子节点是否为空

                let classStr = !parent && !hasChild ? 'c-tree-btn-empty'
                    : open ? 'c-tree-btn-reduice' : 'c-tree-btn-add';

                if (this.level === 1) {
                    // 根节点,都显示按钮，只区别是否展开，和有无子节点
                    classStr = !open ? 'c-tree-btn-add-root'
                        : hasChild ? 'c-tree-btn-reduice-root' : 'c-tree-btn-empty-root';

                } else if (this.last) {
                    // 最后一个节点
                    classStr += '-nonext';

                }
                return ['c-tree-btn', classStr];
            },
            // 子列表背景
            classUl() {
                return ['c-tree-ul', {'c-tree-ul-bg': !this.last}];
            },
            classItem() {
                return ['c-tree-item', {'c-tree-item-selected': this.node.selected}];
            },
            stylesUl() {
                return {'background-position-x': 14 * (this.level - 2) + 10 + 'px'};
            },
            stylesItem() {
                const pl = this.level > 1 ? 14 * (this.level - 1) : 0;
                return {paddingLeft: pl + 'px'};
            },
            // 节点图标
            iconName() {
                if (this.node.icon) {return this.node.icon;}
                if (this.node.isParent) {
                    if (this.isOpen) {
                        return 'folder-open';
                    }
                    return 'folder';
                }
                return 'file';
            },
        },
        watch: {
            'node.checked'(val) {
                this.checkVal = val;
            },
        },
        methods: {
            // 展开折叠
            handleClickOpen() {
                if (this.node.isParent || this.node.children.length) {
                    this.isOpen = !this.isOpen;
                    this.setRawVal('open', this.isOpen);
                }
            },
            // 单选
            handleSelect() {
                if (this.showRadio) {
                    this.emitUp('CTree', 'on-select', this.node.id);
                }
            },
            // 选中/取消选中
            handleCheck(val) {
                // 提交给树组件处理
                this.emitUp('CTree', 'on-check', {checked: val, id: this.node.id});
            },
            // 设置原有属性，如果原数据有属性，则设置
            setRawVal(name, val) {
                const k = this.set.key[name];
                if (this.raw.hasOwnProperty(k)) {
                    this.raw[k] = val;
                }
            },
        }
    };
</script>

